package db

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/zeromicro/go-zero/core/logx"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"payme3000/framework/errorx"
	"time"
)

func GetMysqlDsn(config *Config) string {
	return fmt.Sprintf(
		"%s:%s@tcp(%s)/%s?charset=utf8mb4&timeout=30s&interpolateParams=true&parseTime=true",
		config.Username,
		config.Password,
		config.Host,
		config.Db,
	)
}

func CreateGormMysql(dbType Type, config *Config) error {
	gormLock.Lock()
	defer gormLock.Unlock()

	// 锁定后再检查一次
	if gormDb := gormMap[dbType]; gormDb != nil {
		return nil
	}

	mysqlDb, err := sql.Open("mysql", GetMysqlDsn(config))
	if err != nil {
		return errorx.Throw(context.Background(), err)
	}

	mysqlDb.SetMaxOpenConns(12)
	mysqlDb.SetMaxIdleConns(12)
	mysqlDb.SetConnMaxLifetime(1 * time.Hour)
	mysqlDb.SetConnMaxIdleTime(30 * time.Minute)

	if err := mysqlDb.Ping(); err != nil {
		errorx.Catch(context.Background(), mysqlDb.Close())
		return errorx.Throw(context.Background(), err)
	}

	gormDb, err := gorm.Open(
		mysql.New(mysql.Config{
			Conn: mysqlDb,
		}),
		&gorm.Config{
			PrepareStmt:            false,
			SkipDefaultTransaction: true,
		},
	)
	if err != nil {
		errorx.Catch(context.Background(), mysqlDb.Close())
		return errorx.Throw(context.Background(), err)
	}

	gormMap[dbType] = gormDb

	logx.Infof("create gorm mysql done with dbType:%d, host:%s, db:%s", dbType, config.Host, config.Db)

	return nil
}
